package fr.inria.phoenix.scenario.bwsnfirefighting.framework.distributed.logmanager;

import java.util.HashMap;

import fr.inria.diagen.core.ServiceConfiguration;
import fr.inria.diagen.core.exception.DiaGenException;
import fr.inria.diagen.core.exception.InvocationException;
import fr.inria.diagen.core.network.RemoteServiceInfo;
import fr.inria.diagen.core.service.local.Service;

import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel;
import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DeviceStatus;
import java.lang.Integer;
import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.Location;

import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.StatusDetectionDataType;
import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.StatusDetectionIndices;import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.AlertDetectionDataType;
import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.AlertDetectionIndices;
import fr.inria.diagen.core.service.proxy.Proxy;
import fr.inria.diagen.core.module.event.IEventNotifyListener;
import fr.inria.diagen.core.service.filter.service.ServiceFilter;
import fr.inria.diagen.core.server.local.EventSubscription;
import fr.inria.diagen.core.exception.InvocationException;

/**
 * Controller which takes care of the logs
 *
 * @[114,0]
 * controller LogManager{
 * context StatusDetection;
 * context AlertDetection;
 * }
 */
public abstract class LogManager extends Service implements IEventNotifyListener {
  /**
     * @param serviceConfiguration
     */
    public LogManager(ServiceConfiguration serviceConfiguration ) {
      super("LogManager", serviceConfiguration, GeneratedFramework.getInstance());
    }

    protected final void _postInitialize() {
        subscribeStatusDetection();
        subscribeAlertDetection();

        postInitialize();
    }

    protected void postInitialize() {}


    public void notifyReceived(RemoteServiceInfo servicePublisher, String eventName, Object arg) {
        try {
          if (eventName.equals("StatusDetection") && servicePublisher.getClassName().equals("StatusDetection")) {
            StatusDetectionDataType data = (StatusDetectionDataType) arg;
            onNewStatusDetection ((fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DeviceStatus) data._dataSourceValue_, data.indices.id);          }
 else          if (eventName.equals("AlertDetection") && servicePublisher.getClassName().equals("AlertDetection")) {
            AlertDetectionDataType data = (AlertDetectionDataType) arg;
            onNewAlertDetection ((fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel) data._dataSourceValue_, data.indices.location);          }

        } catch (Exception e) {
              e.printStackTrace();
        }
    }

    public abstract void onNewStatusDetection(fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DeviceStatus newStatusDetectionValue, java.lang.Integer id);
    
    
    private final void subscribeStatusDetection() {
      getServer().subscribe(new EventSubscription(getStatusDetectionRSI(), getServiceInfo(), "StatusDetection"), 3600);
    }

    private RemoteServiceInfo getStatusDetectionRSI() {
      ServiceFilter filter = new ServiceFilter("StatusDetection");
      RemoteServiceInfo[] rsis = getServicesInfo(getServer(), filter);
      return rsis[0];
    }
    
    protected final fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DeviceStatus getStatusDetection(java.lang.Integer id) throws InvocationException {
      return (fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DeviceStatus) getProcessor().command(getStatusDetectionRSI(), "getStatusDetection", id);
    }    public abstract void onNewAlertDetection(fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel newAlertDetectionValue, fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.Location location);
    
    
    private final void subscribeAlertDetection() {
      getServer().subscribe(new EventSubscription(getAlertDetectionRSI(), getServiceInfo(), "AlertDetection"), 3600);
    }

    private RemoteServiceInfo getAlertDetectionRSI() {
      ServiceFilter filter = new ServiceFilter("AlertDetection");
      RemoteServiceInfo[] rsis = getServicesInfo(getServer(), filter);
      return rsis[0];
    }
    
    protected final fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel getAlertDetection(fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.Location location) throws InvocationException {
      return (fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel) getProcessor().command(getAlertDetectionRSI(), "getAlertDetection", location);
    }

} 